# !/usr/bin/env python
# -*-coding:utf-8 -*-

"""
# File       : debug_runner.py
# Time       ：2024/5/16 19:28
# Author     ：YangYong
# version    ：python 3.10
# Description：
    debug模式运行任务
"""
import traceback

from orderlines.execute.app_context import AppContext
from orderlines.execute.base_runner import BaseRunner
from orderlines.execute.states.process_finite_state_machines import ProcessInstanceState
from orderlines.execute.states.task_finite_state_machines import TaskInstanceState
from orderlines.execute.task_build import TaskBuild
from orderlines.utils.exceptions import OrderLineRunningException
from orderlines.utils.orderlines_enum import TaskStates
from public.logger import logger


class DebugRunner(BaseRunner):
    def __init__(self, process_instance_id: str, context: AppContext):
        super(DebugRunner, self).__init__(process_instance_id, context)
        self.running_db_operator = self.process_parse.task_parse.running_db_operator
        self.running_db_operator.process_instance_insert(self.process_info)
        self.task_fsm = TaskInstanceState(self.task_instance_id(), self.process_id, self.process_instance_id)
        self.process_fsm = ProcessInstanceState(self.process_instance_id)
        self.process_fsm.trigger_chance('start')
        self.debug_mode = False  # 表示着当前是不是debug模式，True表示debug模式，False表示非debug模式
        self.pre_task_name = None

    def get_signal(self) -> str:
        # 获取任务指令
        pass

    def task_generate(self, task_name):
        task_build = TaskBuild(self.process_instance_id, self.current_node())
        task_result = task_build.build_task(self.current_task_id, self.process_info, self.task_nodes)
        logger.info(
            f'current_task_id:{self.current_task_id},task_name:{task_name},task result:{task_result}',
            task_instance_id=self.task_instance_id()
        )
        yield task_result

    def debug_task_run(self):
        """
        debug模式介绍
        1、debug模式不使用进程方式运行任务
        2、进入到debug模式的方式
            2.1、process mode参数设置为debug
            2.2、任务有运行失败或者是在指定任务设置断点
        3、debug模式运行方式
            debug模式下任务运行失败，不会停止任务只会跳过该任务，供开发者调试后，发送继续流程继续运行
            进入debug模式，此时流程暂停供开发人员进行排查，排查完成后点击继续按钮，进入到运行模式，当任务运行遇到错误，流程继续暂停供开发排查
        """
        while self.is_complete:
            task_kwargs: dict = self.process_parse.task_parse.task_kwargs(self.current_task_id)
            self.process_parse.generate_task()
            generator = self.task_generate(self.task_name())

            logger.info(
                f'debug模式:{self.debug_mode}.'
                f'流程id:{self.process_instance_id}, 任务名称:{self.task_name()}开始运行。任务参数:{task_kwargs}',
                task_instance_id=self.task_instance_id()
            )
            if self.debug_mode:
                tip_text = f'【{self.pre_task_name}】运行失败进入debug模式，请输入操作信号，s->stop停止流程，c->continue继续流程.\n'
                sign = input(tip_text).strip()
                if sign in ['s', 'stop']:
                    logger.info(
                        f'流程id:{self.process_instance_id},流程结束，当前任务为:{self.task_name()}',
                        task_instance_id=self.task_instance_id()
                    )
                    break
                elif sign in ['c', 'continue']:
                    result = generator.send(None)
                    self.debug_mode = False
                else:
                    raise OrderLineRunningException(f'未知信号{sign}')

            else:
                result = generator.send(None)

            if result.get('status') == TaskStates.green.value:
                self.task_fsm.trigger_chance('success', result)
            else:
                self.task_fsm.trigger_chance('failure', result)
                self.task_fsm.trigger_chance('skip', result)
                self.debug_mode = True
                self.pre_task_name = self.task_name()

            logger.info(
                f'流程id:{self.process_instance_id}, 任务名称:{self.task_name()}运行结束。\n运行结果:{result}',
                task_instance_id=self.task_instance_id()
            )
            self.is_complete = self.process_parse.task_parse.is_complete()
            self.current_task_id = self.process_parse.consumer_task()
            if self.current_task_id:
                self.running_db_operator.task_instance_insert(self.current_node())
                self.task_fsm = TaskInstanceState(self.task_instance_id(), self.process_id, self.process_instance_id)
                self.task_fsm.trigger_chance('start')
                self.message_id = self.process_parse.message_id()
            else:
                self.process_fsm.trigger_chance('success')

    def debug(self):
        self.running_db_operator.task_instance_insert(self.current_node())
        self.task_fsm.trigger_chance('start')
        logger.info('开始进入debug run模式', task_instance_id=self.task_instance_id())
        try:
            self.debug_task_run()
        except Exception as error:
            logger.error(f'流程运行失败：：{traceback.format_exc()}', task_instance_id=self.task_instance_id())
            self.task_fsm.trigger_chance('failure', str(error))
            self.process_fsm.trigger_chance('failure', str(error))
